#pragma once

#include <vector>
#include <unordered_map>

#include "../utility/Noncopyable.h"
#include "../utility/Timestamp.h"

class Channel;
class EventLoop;

// EventLoop：reactor；Poller：多路复用器；Channel：事件+事件处理器
// 抽象类，用于支持不同派生类如poll、epoll
class Poller : Noncopyable
{
public:
    using ChannelVector = std::vector<Channel *>;

    Poller(EventLoop *loop);
    virtual ~Poller() = default;

    // EventLoop通过该接口获取默认IO复用的具体实现
    // muduo默认没设置环境变量则返回epoll
    // 返回Poller* 派生类对象的静态方法
    // 如果在Poller.cpp写实现，该实现要返回派生类则要包含派生类.h，基类包含引用派生类设计不好
    // 所以放在DefaultPoller.cc单独实现
    static Poller *getDefaultPoller(EventLoop *loop); // poller构造需要loop

    // channel是否在Poller中
    bool hasChannel(Channel *chan) const;

    // IO复用统一接口，poller操作channel
    virtual void updateChannel(Channel *chan) = 0;
    virtual void removeChannel(Channel *chan) = 0;
    virtual Timestamp poll(const int timeoutMs, ChannelVector *activeChans) = 0;

protected:
    // fd-fd所属的channel
    // TODO: 实际上用std::unordered_set<Channel *>也可以查找，不需要进一步获取fd
    using ChannelMap = std::unordered_map<int, Channel *>;
    ChannelMap fdToChanMap_;

private:
    EventLoop *loop_; // 所属loop
};